<template>
  <u-popup v-model="show" mode="bottom" :mask="false" @close="bindClose()" v-if="show">
    <div class="title">文字 {{ textOption.__id__ }}</div>

    <div class="input">
      <u-input
        v-model="textOption.textStr"
        :clearable="false"
        :auto-height="false"
        :height="40"
        type="textarea"
        placeholder="请输入内文案"
        :border="false"
        :custom-style="{
          height: '50rpx',
        }"
      />
    </div>
    <div class="btns">
      <div class="btn" :class="{ active: type == 'font' }" @click="setType('font')">字体</div>
      <div class="btn" :class="{ active: type == 'style' }" @click="setType('style')">样式</div>
      <div class="btn" :class="{ active: type == 'color' }" @click="setType('color')">颜色</div>
      <!--      <div class="btn" @click="type = 'font'">描边</div>-->
      <!--      <div class="btn" @click="type = 'font'">形状</div>-->
    </div>

    <div class="scroll-body">
      <scroll-view scroll-y="true" style="height: 300rpx">
        <view v-if="type == 'font'" class="font-body">
          <view
            v-for="item in fontsList"
            :key="item.id"
            class="font-li"
            :class="{
              active: textOption.textStyle.fontFamily === item.cateName,
            }"
            @click="setFontFace(item)"
          >
            <view class="truncate font-name">{{ item.cateName }}</view>
            <image v-if="!item.isLoading" src="https://cos.aitshirt.cn/app-icon/%E4%B8%8B%E8%BD%BD%402x.png"></image>
          </view>
        </view>
        <view v-if="type == 'style'" class="font-body style-li">
          <div
            v-for="item in fontStyles"
            :key="item.name"
            class="style-item"
            :class="{
              active: textOption.textStyle[item.fontKey] === item.key,
            }"
            @click="setFontObj(item)"
          >
            <i class="iconfont" :class="item.icon"></i>
          </div>
        </view>
        <view v-if="type == 'color'" class="font-body" style="display: flex">
          <!--       :color="textOption.textStyle.color"            -->
          <ColorSlider style="width: 100%; margin: 20rpx" @change="change">
            <div
              class="now-color-box"
              :style="{
                backgroundColor: textOption.textStyle.color,
              }"
            ></div>
          </ColorSlider>
        </view>
      </scroll-view>
    </div>
  </u-popup>
</template>
<script setup lang="ts">
import { ref, onMounted, shallowRef, unref, inject, toRaw, reactive, watch } from 'vue';
import { getfonts } from '@/api/designApi';
import { type FontStyle, getFont } from '@/utils/canvasTools';
import { cloneDeep } from 'lodash';
import { ColorSlider } from '@/components/color-slider/color-slider.vue';
import { Debounce } from '@/utils/tool';

const emit = defineEmits(['change']);
const type = ref('font');
const setType = (val) => {
  type.value = val;
};

const change = (e: string) => {
  // console.log('color change', e);
  textOption.textStyle.color = e;
  submit();
};

const modelCanvasCtx = inject('modelCanvasCtx');

const setFontFace = (item) => {
  uni.loadFontFace({
    family: item.cateName,
    source: `url("${item.down}")`,
    success() {
      console.log('字体加载成功');
      item.isLoading = true;
      textOption.textStyle.fontFamily = item.cateName;
      submit();
    },
    fail(e) {
      console.log('字体加载失败', e);
    },
  });
};

const setFontObj = (item) => {
  if (['left', 'center', 'right', 'horizontal', 'vertical'].includes(item.key)) {
    textOption.textStyle[item.fontKey] = item.key;
  } else if (['bold', 'underline', 'flipH', 'flipV'].includes(item.key)) {
    textOption.textStyle[item.fontKey] = textOption.textStyle[item.fontKey] === item.key ? '' : item.key;
  } else if (item.key === 'italic') {
    textOption.textStyle[item.fontKey] = textOption.textStyle.fontStyle === 'italic' ? '' : 'italic';
  } else if (['add', 'subtract'].includes(item.key)) {
    textOption.textStyle.fontSize += item.key === 'add' ? 1 : -1;
  } else if (['letterSpacingAdd', 'letterSpacingSubtract'].includes(item.key)) {
    textOption.textStyle[item.fontKey] += item.key === 'letterSpacingAdd' ? 1 : -1;
  } else if (['flipX', 'flipY'].includes(item.key)) {
    textOption.textStyle[item.fontKey] = textOption.textStyle[item.fontKey] === 1 ? -1 : 1;
  }
  // console.log('s<><><><><><>', textOption.textStyle);
  submit();
};

const textOption = reactive({
  __id__: '',
  textStr: 'ad\n大苏打\n哇\n撒\n大\n苏\nasd',
  textStyle: {
    fontFamily: 'sans-serif',
    fontSize: 24,
    fillStyle: '#0063ff',
    direction: 'horizontal',
    fontWeight: 'bold',
    fontStyle: 'italic',
    underline: true,
    flipX: 1,
    flipY: 1,
    lineHeight: 1,
    letterSpacing: 0,
    textAlign: 'left',
    scale: 0,
    width: 0,
    height: 0,
    leftX: [],
    color: 'rgba(242, 90, 39, 1)',
  },
});

watch(
  () => textOption.textStr,
  (value, oldValue, onCleanup) => {
    if (value !== oldValue) {
      submit();
    }
  },
);

const submit = Debounce(() => {
  const _textStyle = toRaw(textOption.textStyle);
  modelCanvasCtx.value.font = getFont(_textStyle);

  const isHorizontal = _textStyle.direction === 'horizontal';
  const widthArr = textOption.textStr?.split('\n').map((txt) => {
    // return modelCanvasCtx.value.measureText(txt).width + (txt.split('').length - 1) * (isHorizontal ? _textStyle.letterSpacing : 0);
    return modelCanvasCtx.value.measureText(txt).width + (txt.split('').length - 1) * _textStyle.letterSpacing;
  });
  console.log('widthArr', widthArr);
  const txtWidth = Math.max(...widthArr);
  if (_textStyle.textAlign === 'right') {
    textOption.textStyle.leftX = widthArr.map((w) => txtWidth - w);
  } else if (_textStyle.textAlign === 'center') {
    textOption.textStyle.leftX = widthArr.map((w) => (txtWidth - w) / 2);
  } else {
    textOption.textStyle.leftX = widthArr.map(() => 0);
  }

  const height = textOption.textStyle.fontSize * textOption.textStyle.lineHeight * textOption.textStr.split('\n').length;

  const wordOption = unref(textOption);
  wordOption.textStyle.width = textOption.textStyle.direction === 'horizontal' ? txtWidth : height;
  wordOption.textStyle.height = textOption.textStyle.direction === 'horizontal' ? height : txtWidth;

  // console.log('textOption', wordOption);

  emit('change', wordOption);
}, 300);

const fontsList = ref([]);

onMounted(() => {
  getfonts().then((res) => {
    fontsList.value = res.data[0].children;
  });
});

const fontStyles = shallowRef([
  {
    name: '左对齐',
    key: 'left',
    icon: 'icon-zuoduiqi',
    fontKey: 'textAlign',
  },
  { name: '居中', key: 'center', icon: 'icon-juzhong', fontKey: 'textAlign' },
  {
    name: '右对齐',
    key: 'right',
    icon: 'icon-youduiqi',
    fontKey: 'textAlign',
  },
  { name: '加粗', key: 'bold', icon: 'icon-jiacu', fontKey: 'fontWeight' },
  { name: '斜体', key: 'italic', icon: 'icon-xieti', fontKey: 'fontStyle' },
  {
    name: '下划线',
    key: 'underline',
    icon: 'icon-xiahuaxian',
    fontKey: 'underline',
  },
  {
    name: '水平翻转',
    key: 'flipX',
    icon: 'icon-shuipingfanzhuan-1',
    fontKey: 'flipX',
  },
  {
    name: '垂直翻转',
    key: 'flipY',
    icon: 'icon-chuizhifanzhuan',
    fontKey: 'flipY',
  },
  { name: '放大', key: 'add', icon: 'icon-fangda', fontKey: 'fontSize' },
  {
    name: '缩小',
    key: 'subtract',
    icon: 'icon-suoxiao-1',
    fontKey: 'fontSize',
  },
  {
    name: '行距',
    key: 'letterSpacingAdd',
    icon: 'icon-zijianju',
    fontKey: 'letterSpacing',
  },
  {
    name: '行高',
    key: 'letterSpacingSubtract',
    icon: 'icon-shangxiajianju',
    fontKey: 'letterSpacing',
  },
  {
    name: '水平放置',
    key: 'horizontal',
    icon: 'icon-shangxiayi-copy',
    fontKey: 'direction',
  },
  {
    name: '垂直放置',
    key: 'vertical',
    icon: 'icon-shangxiayi',
    fontKey: 'direction',
  },
]);

const colorHex = ref('');
const bindColorChange = (color) => {
  colorHex.value = color;
};

const show = ref(false);
const open = (node: any) => {
  show.value = true;
  if (node) {
    textOption.textStr = node._textStr;
    textOption.textStyle = { ...cloneDeep(node._textStyle), flipX: node.flipX, flipY: node.flipY };
    textOption.__id__ = node.__id__;
  }
  console.log('打开文字设置', node);
};
const setId = (id) => {
  textOption.__id__ = id;
};

defineExpose({
  open,
  setId,
});

const bindClose = () => {
  show.value = false;
  textOption.textStr = '';
  textOption.__id__ = '';
  textOption.textStyle = {
    fontFamily: '',
    fontSize: 24,
    fillStyle: '#0063ff',
    direction: 'horizontal',
    fontWeight: 'bold',
    fontStyle: 'italic',
    underline: true,
    flipX: 1,
    flipY: 1,
    lineHeight: 1,
    letterSpacing: 0,
    textAlign: 'left',
    scale: 0,
    width: 0,
    height: 0,
    leftX: [],
    color: 'rgba(242, 90, 39, 1)',
  };
};
</script>

<style scoped lang="scss">
.title {
  font-weight: bold;
  font-size: 32rpx;
  color: #222222;
  line-height: 42rpx;
  text-align: center;
  padding: 32rpx 0;
}

.input {
  font-weight: bold;
  font-size: 28rpx;
  color: #666666;
  line-height: 38rpx;
  text-align: left;
  //padding: 0 0 24rpx;
  margin: 0 32rpx;
  border-bottom: 1rpx solid #e4e4e4;
}

.btns {
  display: flex;
  align-items: center;
  gap: 14rpx;
  padding: 32rpx 32rpx 0;
  .btn {
    width: 104rpx;
    height: 48rpx;
    border-radius: 8rpx 8rpx 8rpx 8rpx;
    font-weight: 400;
    font-size: 28rpx;
    line-height: 48rpx;
    text-align: center;
    background: #f3f7f8;
    color: #6f6f6f;
    &.active {
      color: #ffffff;
      background: #f25a27;
    }
  }
}

.scroll-body {
  padding: 32rpx;
}
.font-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16rpx;

  .font-li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 330rpx;
    height: 80rpx;
    background: #f3f7f8;
    border-radius: 8rpx 8rpx 8rpx 8rpx;
    border: 2rpx solid transparent;
    padding: 0 24rpx;
    gap: 20rpx;
    &.active {
      border: 2rpx solid #f25a27;
    }
    .font-name {
      font-weight: 400;
      font-size: 28rpx;
      color: #222222;
    }
    image {
      width: 32rpx;
      height: 28rpx;
    }
  }
}

.style-li {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 40rpx 0;
  padding: 40rpx 0;
  .style-item {
    width: 56rpx;
    height: 56rpx;
    border-radius: 50%;
    text-align: center;
    line-height: 56rpx;
    &.active {
      background: #f3f7f8;
    }
  }
  .iconfont {
    font-size: 28rpx;
    color: #222222;
  }
}

.now-color-box {
  width: 102rpx;
  height: 102rpx;
  border-radius: 50%;
}
</style>
